/*
 * memory.h
 *
 *  Created on: Jan 21, 2013
 *      Author: Ian Smith, Travis Drake
 */

#ifndef guard_memory
#define guard_memory


#include <stdlib.h>
#include "register.h"
#include "global.h"

#define MEMORY_SIZE_BYTES 0x10000

 /*
  * Represents a bank of memory and two control registers.
  */
typedef struct
{
	/*
	 * A pointer to the first memory location.
	 */
	Byte mem_block[MEMORY_SIZE_BYTES];

	/*
	 * The address in memory to read/write from/to.
	 */
	RegisterStr mar;

	/*
	 * The data to be written or the data just read.
	 */
	Byte mdr;
} MemoryStr;

typedef MemoryStr * MemoryPtr;

/*
 * Initializes a new memory bank.
 */
MemoryPtr Memory_newMemory(void);

/*
 * Sets the address at which the next read or write will occur.
 * memory: A pointer to the memory to modify.
 * value: The new value to set.
 */
void Memory_setMemoryAddressRegister(MemoryPtr memory, unsigned short value);

/*
 * Sets the data to be written to memory.
 * memory: A pointer to the memory to modify.
 * value: The new value to set.
 */
void Memory_setMemoryDataRegister(MemoryPtr memory, Byte value);

/*
 * Gets the data most recently read from memory.
 * memory: A pointer to the memory to query.
 */
Byte Memory_getMemoryDataRegister(MemoryPtr memory);

/*
 * Gets the memory value at the address register and puts it in the data
 * register. This operation is undefined if the address register hasn't been
 * set.
 * memory: A pointer to the memory to query.
 */
void Memory_performRead(MemoryPtr memory);

/*
 * Sets the memory value at the address register to the value contained in the
 * data register. This operation is undefined if the address register or the
 * data register hasn't been set.
 */
void Memory_performWrite(MemoryPtr memory);

/*
 * Initializes the memory block to all random values.
 * memory: The memory to initialize.
 */
void Memory_initialize(MemoryPtr memory);

/*
 * Frees the memory object from system memory.
 * memory: The memory to delete.
 */
void Memory_deleteMemory(MemoryPtr memory);

#endif /* guard_memory */
